package com.runa.monitor.platinterface.netservice.handler;

import com.runa.persistence.util.LogUtil;
import com.runa.protocol.analysis.DataAnalysis;
import com.runa.protocol.analysis.ShellBufferAnalysis;
import com.runa.protocol.util.ByteUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.socket.DatagramPacket;
import io.netty.handler.codec.MessageToMessageDecoder;
import io.netty.util.AttributeKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author zhuj
 */
public class DatagramDecoder extends MessageToMessageDecoder<DatagramPacket> {

    private static final Logger logger = LoggerFactory.getLogger(DatagramDecoder.class);

    private DataAnalysis<byte[]> analysis;

    DatagramDecoder(DataAnalysis<byte[]> analysis) {
        this.analysis = analysis;
    }

    private static final Map<String, String> map = new ConcurrentHashMap<>();

    @Override
    protected void decode(ChannelHandlerContext ctx, DatagramPacket packet, List<Object> out) {
        byte[] data = new byte[packet.content().readableBytes()];
        packet.content().readBytes(data);
        String addr = null;
        try {
            String hostAddress = packet.sender().getAddress().toString() + ":" + packet.sender().getPort();
            String serial = map.get(hostAddress);
            LogUtil.info(serial, data, "收到 {} {} ", hostAddress, ctx.channel().id());
            analysis.fill(data, data.length, serial);
            if (analysis instanceof ShellBufferAnalysis) {
                addr = ((ShellBufferAnalysis<?>) analysis).netEquNo;
                if (addr != null) {
                    AttributeKey<DatagramPacket> key = AttributeKey.valueOf(addr);
                    ctx.channel().attr(key).set(packet);
                    map.put(hostAddress, addr);
                }
            }
            if (analysis.gain() != null) {
                out.add(analysis.gain());
            }
        } catch (Exception e) {
            logger.error("DatagramDecoder Error: ", e);
        } finally {
            logger.debug("DatagramDecoder From {}: {}, remote:{}", addr, ByteUtil.byteToHexString(data), packet.sender());
        }
    }

}
